/****************************************************************************/
/* NAME:           temperature.c                                            */
/* PURPOSE:        Manage all oscillator                                    */
/* CREATED_BY:     Vyx                                                      */
/* CREATION_DATE:  07/07/2012                                               */
/************************************** (C) Copyright 2012 AquaLink *********/

#include "temperature.h"


#define TEMP_TASK_DELAY      (60000) /*  60s */
#define Sample_TASK_DELAY    (500)   /* 0.5s */

Temp_def_t temps[] =
{
    {0, TEMP_SENSOR_0, FAN_WATER, 25.0, 0, TRUE},
    {1, TEMP_SENSOR_1, FAN_LIGHT, 45.0, 0, FALSE},
};

#define TEMP_NUMBER (sizeof(temps) / sizeof(temps[0]))

/**
  * @brief  Main function of temperature.
  * @param  none
  * @retval None
  */
void vTaskCTRL_TEMPERATURE()
{
    portTickType xLastWakeTime;
    double       TempTmp[NB_SAMPLE_TEMP];
    double       AverageTemp;
    double       MesuredTemp;
    uint8_t      TempSample;
    uint8_t      TempNb;
    bool         SampleState;

    /* init */
    AverageTemp   = 0;
    MesuredTemp   = 0;
    TempSample    = 0;
    SampleState   = TRUE;
    xLastWakeTime = xTaskGetTickCount();

    init_TEMPERATURE();

    while(1)
    {
        for (TempNb = 0; TempNb < TEMP_NUMBER; TempNb++)
        {
            /* averaging loop */
            for (TempSample = 0;(TempSample < NB_SAMPLE_TEMP) || (SampleState != FALSE); TempSample++)
            {
                if (ReadTemp(&MesuredTemp, temps[TempNb].temp_addr) == TRUE)
                {
                    TempTmp[TempSample] = MesuredTemp;
                }
                else
                {
                    SampleState = FALSE;   /* Do not compute average temp if error occur */
                }

                wait(Sample_TASK_DELAY);
            }

            /* if no error compute average temperature */
            if ( SampleState == FALSE )
            {
                // error
            }
            else
            {
                /* comptute average */
                for ( TempSample = 0; TempSample < NB_SAMPLE_TEMP; TempSample++ )
                {
                    AverageTemp += TempTmp[TempSample];
                }
                AverageTemp /= NB_SAMPLE_TEMP;

                /* update temps */
                temps[TempNb].temp_value = AverageTemp;
            }

            wait(TEMP_TASK_DELAY);
        }
    }
}

/**
  * @brief  Init function of temperature.
  * @param  none
  * @retval None
  */
void init_TEMPERATURE()
{
  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = I2C2_ER_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  TMP100_Init();
}

/**
  * @brief  Read temperature
  * @param  Temp to be read, address of sensor to be read
  * @retval Read status
  */
bool ReadTemp(double *temp, uint8_t AddressSensor)
{
    int32_t TempValue;
    bool    Status;

    Status = FALSE;

    TempValue = TMP100_ReadTemp(AddressSensor);
    if ( (TempValue >= _TEMP_MIN) && (TempValue <= _TEMP_MAX) )
    {
        *temp  = TempValue*_TEMP_RESOLUTION;
        Status = TRUE;
    }

    return (Status);
}

/**
  * @brief  Read temperature
  * @param  address of sensor to be read
  * @retval Temp read
  */
void ReadDebouncedTemp(double *temp, FAN_SETPOINT_ROLE role)
{
    uint8_t TempNb;

    for (TempNb = 0; TempNb < TEMP_NUMBER; TempNb++)
    {
        if (temps[TempNb].role == role)
        {
            *temp = temps[TempNb].temp_value;
            break;
        }
    }
}

/**
  * @brief  Get set point of sensor
  * @param  address of sensor to be read
  * @retval Temp read
  */
void TEMP_GetSetpointTemp(double *setPoint, FAN_SETPOINT_ROLE role)
{
    uint8_t TempNb;

    for (TempNb = 0; TempNb < TEMP_NUMBER; TempNb++)
    {
        if (temps[TempNb].role == role)
        {
            *setPoint = temps[TempNb].setPoint;
            break;
        }
    }
}

/**
  * @brief  Set set point of sensor
  * @param  address of sensor to be read
  * @retval Temp read
  */
void TEMP_SetSetpointTemp(double *setPoint, FAN_SETPOINT_ROLE role)
{
    uint8_t TempNb;

    for (TempNb = 0; TempNb < TEMP_NUMBER; TempNb++)
    {
        if (temps[TempNb].role == role)
        {
            temps[TempNb].setPoint = *setPoint;
            break;
        }
    }
}
